﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Threading;
using System.Collections;
using System.Collections.ObjectModel;
using System.IO; 


namespace SharePointManagementStudio
{
    public partial class frmSolutionProperties : Form
    {
        private string strsolution;
        private string action;

        public frmSolutionProperties()
        {
            InitializeComponent();
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

            backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
            backgroundWorker2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker2_RunWorkerCompleted);
        }
        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            ConnectToFarm();
        }

        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            toolStripProgressBar1.Value = 100;
            toolStripProgressBar1.Value = 0;
            timer1.Stop();
            btnConnectFarm.Enabled = true; 
        }

        private void btnConnectFarm_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            btnConnectFarm.Enabled = false;
            backgroundWorker2.RunWorkerAsync();  
        }

        private void ConnectToFarm()
        {
            this.BeginInvoke(new MethodInvoker(delegate()
            {
                appendText("Connecting farm pleace wait\n");
            listBox_Solutions.Items.Clear();
            SPSolutionCollection mySolutionColl = SPFarm.Local.Solutions;
            foreach (SPSolution s in mySolutionColl)
            {
                listBox_Solutions.Items.Add(s.DisplayName.ToString());
            }
            if (listBox_Solutions.Items.Count > 0)
            {
                listBox_Solutions.SelectedIndex = 0;
            }
            else
            {
                panel1.Visible = false;
                panel2.Visible = false;
                panel3.Visible = true;  
            }
            appendText("Connected\n");
            }));
        }

        

        private void listBox_Solutions_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                propertyGrid1.SelectedObject = GetSolutionProperties(listBox_Solutions.SelectedItem.ToString());
                DeterminateWichPanelShow(GetSolutionProperties(listBox_Solutions.SelectedItem.ToString()));
            }
            catch { }
        }


        private void DeterminateWichPanelShow(SolutionPropertiesgrid s)
        {
            this.BeginInvoke(new MethodInvoker(delegate()
            {

                if (s.ContainsWebApplicationResource == true )
                {
                    panel2.Visible = true;
                    panel1.Visible = false;

                    this.ListBoxAvalibleApps.Items.Clear();
                    this.ListBoxDeployedto.Items.Clear();   
                    SPFarm spf = SPFarm.Local;
                    SPWebService spws = spf.Services.GetValue<SPWebService>("");

                    foreach (SPWebApplication app in spws.WebApplications)
                    {
                        try
                        {
                            this.ListBoxAvalibleApps.Items.Add(app.Sites[0].RootWeb.Url.ToString());
                        }
                        catch { }
                    }

                    //------------------------ Wepp app Deployed solution -----------------//
                    if (s.DeploymentStatus == "Not Deployed")
                    {
                        this.btnRectractWebapp.Enabled = false;                        
                    }
                    else
                    {
                        this.btnRectractWebapp.Enabled = true;

                        SPSolution solution = GetSolutionByName(s.Name);
                        if (solution.DeployedWebApplications != null)
                        {
                            foreach (SPWebApplication  app in solution.DeployedWebApplications)
                            {
                                this.ListBoxAvalibleApps.Items.Remove(app.Sites[0].RootWeb.Url.ToString());
                                ListBoxDeployedto.Items.Add(app.Sites[0].RootWeb.Url.ToString());  
                            }
                        } 

                    }
                }


                if (s.ContainsGlobalAssembly == true && s.ContainsWebApplicationResource == false)
                {
                    //------------------------ Global Deployed solution -----------------//
                    if (s.DeploymentStatus == "Deployed")
                    {
                        panel2.Visible = false;
                        panel1.Visible = true;
                        btnRemoveSolution.Enabled = false;                    
                        btnRetractSolution.Enabled = true;
                        btnDeploy.Enabled = false; 
                    }
                    else
                    {
                        panel2.Visible = false;
                        panel1.Visible = true;
                        btnRemoveSolution.Enabled = true;
                        btnRetractSolution.Enabled = false;
                        btnDeploy.Enabled = true;
                    }
                }
            }));
        }

        private SolutionPropertiesgrid GetSolutionProperties(string SolutionName)
        {
            SolutionPropertiesgrid sol = new SolutionPropertiesgrid();
            SPSolutionCollection mySolutionColl = SPFarm.Local.Solutions;


            foreach (SPSolution s in mySolutionColl)
            {
                if (s.DisplayName.ToString() == SolutionName.ToString())
                {
                    sol.Name = SolutionName.ToString();
                    sol.ContainsGlobalAssembly = s.ContainsGlobalAssembly;
                    sol.ContainsCodeAccessSecurityPolicy = s.ContainsCasPolicy;
                    sol.ContainsWebApplicationResource = s.ContainsWebApplicationResource;
                    if (s.Deployed == true)
                    {
                        sol.DeploymentStatus = "Deployed";
                        if (s.ContainsWebApplicationResource == true)
                        {
                            foreach (SPWebApplication app in s.DeployedWebApplications)
                            {
                                sol.DeployedTo += app.Sites[0].RootWeb.Url.ToString() + ";";
                            }
                        }
                        else 
                        {
                            sol.DeployedTo = "Global Deployed";
                        }
                    }
                    else
                    {
                        sol.DeploymentStatus = "Not Deployed";
                    }
                    sol.LastOperationResult = s.LastOperationResult.ToString();
                    sol.LastOperationDetails = s.LastOperationDetails.ToString();
                    sol.LastOperationTime = s.LastOperationEndTime.ToString();  
                }               
            }
            return sol;
        }
       
        private SPSolution GetSolutionByName(string solutionName)
        {
            SPSolutionCollection sc = SPFarm.Local.Solutions;
            foreach (SPSolution s in sc)
            {
                if (s.Name.ToLower() == solutionName.ToLower())
                    return s;
            }

            return null;
        }

        private void appendText(string p)
        {
            this.BeginInvoke(new MethodInvoker(delegate()
            {
                this.richTextBox1.Text += p;
            }));
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum)
            {
                toolStripProgressBar1.Value = 0;
            }
            toolStripProgressBar1.PerformStep();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //Remove solution
            if (action == "RemoveWebAppSolution")
            {
                try
                {
                    appendText(strsolution + " is removing solution store...\n");
                    RemoveSolution(strsolution);
                    appendText("The solution was successfully removed\n");
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        ConnectToFarm(); 
                    }));
                }
                catch (Exception ex)
                {
                    appendText(ex.ToString());
                }
            }

            //Rectract Selectted solution from Webapps
            if (action == "RectractWebAppSolution")
            {
                RectractWebAppSolution(strsolution);
                this.BeginInvoke(new MethodInvoker(delegate()
                {
                    try
                    {
                        propertyGrid1.SelectedObject = GetSolutionProperties(listBox_Solutions.SelectedItem.ToString());
                        DeterminateWichPanelShow(GetSolutionProperties(listBox_Solutions.SelectedItem.ToString()));
                    }
                    catch { }
                }));
            }

            // WebApplication Solution Deploy
            if (action == "DeployWebAppSolution")
            {
                DeployWebAppSolution(strsolution);
                this.BeginInvoke(new MethodInvoker(delegate()
                {
                    try
                    {
                        propertyGrid1.SelectedObject = GetSolutionProperties(listBox_Solutions.SelectedItem.ToString());
                        DeterminateWichPanelShow(GetSolutionProperties(listBox_Solutions.SelectedItem.ToString()));
                    }
                    catch { }
                }));
            }
            
            if (action == "RectractGlobalDeployed")
            {
                try
                {
                    appendText(strsolution + " is Retracting...\n");
                    RectractGlobalDeployedSolution(strsolution);
                    appendText("The solution was successfully retracted. ");
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        btnDeploy.Enabled = true;
                        btnRetractSolution.Enabled = false;
                        btnRemoveSolution.Enabled = true; 
                    }));
                }
                catch (Exception ex)
                {
                    appendText(ex.ToString());  
                }
            }
            if (action == "GlobalDeployesolution")
            {
                try
                {
                    appendText(strsolution + " is Deploying...\n");
                    GlobalDeployedSolution(strsolution);
                    appendText("The solution was successfully deployed\n");
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        btnDeploy.Enabled = false;
                        btnRetractSolution.Enabled = true;
                        btnRemoveSolution.Enabled = false;
                    }));
                }
                catch (Exception ex)
                {
                    appendText(ex.ToString());  
                }
            }
            
            if (action == "RemoveGlobalDeployesolution")
            {
                try
                {
                    appendText(strsolution + " is removing solution store...\n");
                    RemoveSolution(strsolution);
                    appendText("The solution was successfully removed\n");
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        btnDeploy.Enabled = false;
                        btnRetractSolution.Enabled = false;
                        btnRemoveSolution.Enabled = false;
                        //listBox_Solutions.SelectedIndex = -1; 
                        //listBox_Solutions.Items.Remove(strsolution);
                        ConnectToFarm(); 
                    }));
                }
                catch (Exception ex)
                {
                    appendText(ex.ToString());
                }
            }
        }


        private void RectractWebAppSolution(string s)
        {
            SPSolution sol = SPFarm.Local.Solutions[s];
            Collection<SPWebApplication> webapps = new Collection<SPWebApplication>();
            foreach (object itemChecked in this.ListBoxDeployedto.CheckedItems)
            {
                SPWebApplication webapp = SPWebApplication.Lookup(new Uri(itemChecked.ToString()));
                webapps.Add(webapp);
                appendText("Rectracting " + s + " from  " + webapp.Sites[0].RootWeb.Url.ToString() + "\n");
            }
            appendText("Starting rectract for selected Web Applications");
        rect:
            appendText(".");
            try
            {
                Thread.Sleep(5000);
                sol.Retract(DateTime.Now, webapps);                    
            }
            catch
            {
                goto rect;
            }
            Thread.Sleep(8000);
            appendText("\nThe solution was successfully rectracted\n");

        }

        private void DeployWebAppSolution(string s)
        {
            SPSolution sol = SPFarm.Local.Solutions[s];
            Collection<SPWebApplication> webapps = new Collection<SPWebApplication>();
            foreach (object itemChecked in this.ListBoxAvalibleApps.CheckedItems)
            {
                SPWebApplication webapp = SPWebApplication.Lookup(new Uri(itemChecked.ToString()));
                webapps.Add(webapp);
                appendText("Repairing " + s + " to deploy " + webapp.Sites[0].RootWeb.Url.ToString()+ "\n");     
            }
            appendText("Starting Deploy for selected Web Applications");
        deploynow:
            appendText(".");
            try
            {
                Thread.Sleep(5000);
                sol.Deploy(DateTime.Now, false, webapps, true);
            }
            catch
            {
                goto deploynow;
            }
            Thread.Sleep(8000);
            appendText("\nThe solution was successfully deployed\n");

        }

        private void RemoveSolution(string s)
        {
            SPSolution solution = GetSolutionByName(s);
            solution.Delete(); 
            Thread.Sleep(8000);
        }

        private void GlobalDeployedSolution(string s)
        {
            SPSolution solution = GetSolutionByName(s);
            solution.Deploy(DateTime.Now, true, false);
            Thread.Sleep(8000);
        }

        private void RectractGlobalDeployedSolution(string s)
        {
            SPSolution solution = GetSolutionByName(s);
            solution.Retract(DateTime.Now);
            Thread.Sleep(8000);  
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            toolStripProgressBar1.Value = 100;
            toolStripProgressBar1.Value = 0;
            timer1.Stop();
        }

        private void btnRetractSolution_Click(object sender, EventArgs e)
        {
            if(listBox_Solutions.SelectedItem.ToString() != string.Empty)
            {
                strsolution = listBox_Solutions.SelectedItem.ToString();
                action = "RectractGlobalDeployed";
                timer1.Enabled = true;
                backgroundWorker1.RunWorkerAsync();  
            }
            else
            {
                richTextBox1.Text += "Pleace select a solution\n"; 
            }
        }

        private void btnDeploy_Click(object sender, EventArgs e)
        {
            if (listBox_Solutions.SelectedItem.ToString() != string.Empty)
            {
                strsolution = listBox_Solutions.SelectedItem.ToString();
                action = "GlobalDeployesolution";
                timer1.Enabled = true;
                backgroundWorker1.RunWorkerAsync();
            }
            else
            {
                richTextBox1.Text += "Pleace select a solution\n";
            }
        }

        private void btnRemoveSolution_Click(object sender, EventArgs e)
        {
            if (listBox_Solutions.SelectedItem.ToString() != string.Empty)
            {
                strsolution = listBox_Solutions.SelectedItem.ToString();
                action = "RemoveGlobalDeployesolution";
                timer1.Enabled = true;
                backgroundWorker1.RunWorkerAsync();               
            }
            else
            {
                richTextBox1.Text += "Pleace select a solution\n";
            }
        }

        private void btnDeployWebapp_Click(object sender, EventArgs e)
        {
            if (listBox_Solutions.SelectedItem.ToString() != string.Empty)
            {
                if (ListBoxAvalibleApps.CheckedItems.Count > 0)
                {
                    strsolution = listBox_Solutions.SelectedItem.ToString();
                    action = "DeployWebAppSolution";
                    timer1.Enabled = true;
                    backgroundWorker1.RunWorkerAsync();
                }
                else
                {
                    richTextBox1.Text += "Pleace select one or more web applications to deploy.\n";
                    MessageBox.Show("Pleace select one or more web applications to deploy.", "warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);    
                }
            }
            else
            {
                richTextBox1.Text += "Pleace select a solution\n";
                MessageBox.Show("Pleace select a solution", "warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);    
            }
        }

        private void btnRectractWebapp_Click(object sender, EventArgs e)
        {
            if (listBox_Solutions.SelectedItem.ToString() != string.Empty)
            {
                if (ListBoxDeployedto.CheckedItems.Count > 0)
                {
                    if (MessageBox.Show("You are Retracting solution from selected Webapplication\n Do you want continue?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        richTextBox1.Text += "User accepted Retracting.\n";
                        strsolution = listBox_Solutions.SelectedItem.ToString();
                        action = "RectractWebAppSolution";
                        timer1.Enabled = true;
                        backgroundWorker1.RunWorkerAsync();
                    }
                    else 
                    {
                        richTextBox1.Text += "Cancel Retracting.\n";
                    }
                    
                }
                else
                {
                    richTextBox1.Text += "Pleace select one or more web applications to rectract.\n";
                    MessageBox.Show("Pleace select one or more web applications to rectract.","warning", MessageBoxButtons.OK,MessageBoxIcon.Warning);    
                }
            }
            else
            {
                richTextBox1.Text += "Pleace select a solution\n";
                MessageBox.Show("Pleace select a solution", "warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);    
            }
        }

        private void btnRemoveWebapp_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("You are removing solution from solution store\n Do you want continue?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                richTextBox1.Text += "User accepted removing.\n";
                strsolution = listBox_Solutions.SelectedItem.ToString();
                SPSolution solution = GetSolutionByName(strsolution);
                if (solution.DeployedWebApplications.Count > 0)
                {
                    richTextBox1.Text += strsolution + " Deployed one or more web applications. Pleace rectract first.\n";
                }
                else
                {
                    action = "RemoveWebAppSolution";
                    timer1.Enabled = true;
                    backgroundWorker1.RunWorkerAsync();
                    ConnectToFarm();
                }
            }
            else
            {
                richTextBox1.Text += "Cancel Removing.\n";
            }
        }

        private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void btnSaveLog_Click(object sender, EventArgs e)
        {
            DialogResult result = saveFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string file = saveFileDialog1.FileName.ToString();
                string data = richTextBox1.Text;
                Save(file, data);
            }
        }
        private void Save(string file, string data)
        {
            
            StreamWriter writer = new StreamWriter(file);
            writer.Write(data);
            writer.Close();
        } 

    }
}